home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-02-03 | 26.5 KB | 1,012 lines |
- Path: xanth!nic.MR.NET!hal!ncoast!allbery
- From: sid@chinet.UUCP (Sid Grange)
- Newsgroups: comp.sources.misc
- Subject: v05i046: ray tracing program for 3b1
- Message-ID: <12883@ncoast.UUCP>
- Date: 9 Nov 88 03:39:27 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: sid@chinet.UUCP (Sid Grange)
- Lines: 1000
- Approved: allbery@ncoast.UUCP
-
- Posting-number: Volume 5, Issue 46
- Submitted-by: "Sid Grange" <sid@chinet.UUCP>
- Archive-name: tracer
-
- [The author claims that it should be portable to other graphical Un*x systems.
- Since I don't have one handy, I've no way to test that. ++bsa]
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: Makefile README.DOC README.HAK bdata.i conv.c extern.h
- # find.c g_bal.c g_bod.c macros.h refract.c rtd.h shade.c support.c
- # tracer.c
- # Wrapped by sid@chinet on Mon Feb 8 20:03:07 1988
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f Makefile -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"Makefile\"
- else
- echo shar: Extracting \"Makefile\" \(536 characters\)
- sed "s/^X//" >Makefile <<'END_OF_Makefile'
- Xtracer: tracer.o shade.o find.o support.o refract.o g_bod.o g_bal.o
- X cc tracer.o shade.o find.o support.o refract.o g_bod.o g_bal.o -lm -o tracer
- Xfind.o: find.c rtd.h extern.h macros.h
- X cc -c find.c
- Xshade.o: shade.c rtd.h extern.h macros.h
- X cc -c shade.c
- Xsupport.o: support.c rtd.h extern.h
- X cc -c support.c
- Xtracer.o: tracer.c rtd.h bdata.i macros.h
- X cc -c tracer.c
- Xrefract.o: refract.c rtd.h extern.h macros.h
- X cc -c refract.c
- Xg_bod.o: g_bod.c extern.h macros.h
- X cc -c g_bod.c
- Xg_bal.o: g_bal.c extern.h rtd.h
- X cc -c g_bal.c
- END_OF_Makefile
- if test 536 -ne `wc -c <Makefile`; then
- echo shar: \"Makefile\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f README.DOC -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"README.DOC\"
- else
- echo shar: Extracting \"README.DOC\" \(2252 characters\)
- sed "s/^X//" >README.DOC <<'END_OF_README.DOC'
- X
- X
- X
- XTRACER(99) FRITZZ GRAPHICS TRACER(99)
- X
- X
- X
- XNAME
- X tracer- run a simple ray tracing procedure
- X
- XSYNOPSIS
- X tracer -o [filename] -i [filename] -s <filename> -S<number>
- X
- XDESCRIPTION
- X Tracer is a program developed originally to study how
- X ray tracing works, and was later modified to the present state
- X to make it more compatible for animated film production.
- X
- X It is capable of depicting a number of balls (up to 150)
- X and a plane that is covered with a tiling of any bitmapped picture.
- X
- X
- XOPTIONS
- X -o Chooses the output data file. If no argument is givin, stdout
- X is used. If the option is not used the default is data.dis.
- X
- X -i Chooses the input (ball) data file. If no argument is given, stdin
- X is used. If the option is not used the default is bdata.i.
- X
- X -s Chooses the file containing the tiling bitmap. It requires an
- X an argument. If the option is not used the default is pat.def.
- X
- X -S Chooses contrast of the pattern. 0.0 is no contrast, 1.0 is maximum
- X contrast. 1.0 is the default. (useful for fading during animation)
- X
- XPROGRAM NOTES
- X This program generates a file containing a header with x and y sizes,
- X followed by the data in 8-bit greyscale, one pixel to a character, in
- X scanlines.
- X There are two neccessary input files: ball data, and a pattern bitmap.
- X The tiling bitmap can be digitized data, it must be in the form of
- X scan lines no longer than 512 bytes followed by newlines.
- X the ball data is of the following form:
- X
- X x y z rad ior refract reflect diffuse ambient
- X
- X on each line where x y & z are the coordinates of the center of
- X the ball, rad is the radius of the ball, ior is the index of refraction
- X for translucent materials (index of refraction for glass is about 1.5)
- X the last four numbers determine how much of each atrribute is used.
- X Thus a pure silver ball would have 0.0 1.0 0.0 0.0 as the last numbers,
- X and a pure glass ball would have 1.0 0.0 0.0 0.0 .
- X
- X
- XFILES
- X ./bdata.i default ball data
- X ./pat.def default floor pattern
- X ./data.dis default output file
- X
- XBUGS
- X As with any good software, the complexity of this program hides
- X all bugs.
- X
- END_OF_README.DOC
- if test 2252 -ne `wc -c <README.DOC`; then
- echo shar: \"README.DOC\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f README.HAK -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"README.HAK\"
- else
- echo shar: Extracting \"README.HAK\" \(1259 characters\)
- sed "s/^X//" >README.HAK <<'END_OF_README.HAK'
- X***** A Hackers Guide to Tracer *****
- Xtracer consists of a bunch of files containing a program that does
- Xray tracing (No shit sherlock).
- XThes files are as follows:
- Xtracer.c: main() sets up the initial rays and stores values
- X in a file. booboo prints an error message and quits.
- Xshade.c: shade() calculates the intensity returned by a ray. It is
- X recursive, and also makes a call to refract().
- Xrefract.c: The most difficult part of the program. This file contains
- X refract(), inside(), refk() and getcapt().
- X and these do all the refraction calculations.
- Xfind.c: contains find(),findo() (for when a ray is inside a ball)
- X and shadow() and finds() for shadows.
- Xsupport.c: supportive subroutines. right now only contains mt_vec
- X as all the others were either discarded or converted to
- X macros.
- Xg_bal.c g_bal() gets the ball data and points bl[] at them.
- Xg_bod.c g_bod() loads the floor pattern into suzie.
- X
- Xmacros.h contains all the macro definitions. Definitely to be looked at.
- Xrtd.h header file containing all the structure definitions.
- Xextern.h keeps track of all global variables used through the program.
- X
- Xbdata.i sample ball data file.
- X
- Xpat.def \
- Xcheck.pat\
- Xsusie.pat >- sample pattern files. (susie is not for the purient).
- Xship.pat /
- X
- END_OF_README.HAK
- if test 1259 -ne `wc -c <README.HAK`; then
- echo shar: \"README.HAK\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f bdata.i -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"bdata.i\"
- else
- echo shar: Extracting \"bdata.i\" \(213 characters\)
- sed "s/^X//" >bdata.i <<'END_OF_bdata.i'
- X
- X-30.0 10.0 400.0 50.0 0.0 0.0 0.0 0.9 0.1
- X210.0 175.0 400.0 50.0 0.0 0.0 0.3 0.6 0.1
- X40.0 110.0 450.0 50.0 0.0 0.0 0.6 0.3 0.1
- X140.0 65.0 450.0 50.0 0.0 0.0 0.9 0.0 0.1
- X
- X220.0 70.0 100.0 60.0 1.4 0.9 0.0 0.0 0.1
- END_OF_bdata.i
- if test 213 -ne `wc -c <bdata.i`; then
- echo shar: \"bdata.i\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f conv.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"conv.c\"
- else
- echo shar: Extracting \"conv.c\" \(824 characters\)
- sed "s/^X//" >conv.c <<'END_OF_conv.c'
- X#include <stdio.h>
- X#include <tam.h>
- X#include <fcntl.h>
- X
- Xextern errno;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X
- X{
- X char *malloc();
- X char *cd,*d;
- X short *bm,*c;
- X int fd, cont;
- X register int a,b;
- X
- X cont = 60;
- X/* if((argc == 2) && (atoi(argv[1]) >1) && (atoi(argv[1]) <100))
- X cont = atoi(argv[1]);*/
- X
- X if ((fd=open(argv[1],O_RDONLY|O_NDELAY))==0) {
- X fprintf("couldn't open %s for read\n", argv[1]);
- X exit(-1);
- X }
- X if(lseek(fd,8,0)<0)
- X exit(-1);
- X cd=malloc(134400);
- X if(read(fd,cd,134400)!=134400)
- X exit(-1);
- X bm=malloc(14974);
- X c=bm+7487;
- X for(a=287;a>=0;a--) {
- X d=a*420+cd;
- X for(b=415;b>=0;b--) {
- X if(!(b&15))
- X c-=1;
- X *c=(*c<<1)|(*(d+b)>60);
- X }
- X }
- X cd=bm;
- X a = 0;
- X while(a++ != 14974)
- X fprintf(stdout, "%c", *cd++);
- X}
- END_OF_conv.c
- if test 824 -ne `wc -c <conv.c`; then
- echo shar: \"conv.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f extern.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"extern.h\"
- else
- echo shar: Extracting \"extern.h\" \(130 characters\)
- sed "s/^X//" >extern.h <<'END_OF_extern.h'
- Xextern double suzie[300][300],sam;
- Xextern struct ball *bl[];
- Xextern struct sphere ls;
- Xextern int level,nob;
- Xextern int xsue,ysue;
- END_OF_extern.h
- if test 130 -ne `wc -c <extern.h`; then
- echo shar: \"extern.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f find.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"find.c\"
- else
- echo shar: Extracting \"find.c\" \(1942 characters\)
- sed "s/^X//" >find.c <<'END_OF_find.c'
- X#include <math.h>
- X#include "rtd.h"
- X#include "extern.h"
- X#include "macros.h"
- X
- X
- Xdouble findo (m, s) /* finds where a ray inside the ball exits. */
- Xstruct mat *m;
- Xstruct sphere *s;
- X{
- X/* foops id the rotated position vector. */
- X struct vector foops;
- X double t;
- X MTV (foops, (*m), s -> cent);
- X/* see if it hits the ball (it better)*/
- X t = s -> rad * s -> rad - foops.y * foops.y - foops.z * foops.z;
- X if (t > 0)
- X t = foops.x + sqrt (t);
- X else
- X t = 0;
- X/* return how far along the ray you were when you hit */
- X return (t);
- X}
- X
- Xdouble find (m, s)/* finds whether a ray hits a ball*/
- Xstruct mat *m;
- Xstruct sphere *s;
- X{
- X struct vector foops;
- X double t;
- X MTV (foops, (*m), s -> cent);
- X t = s -> rad * s -> rad - foops.y * foops.y - foops.z * foops.z;
- X if (t > 0)
- X t = foops.x - sqrt (t);
- X else
- X t = 0;
- X return (t);
- X}
- X
- Xdouble finds (m, s)/* finds if a ball is between a point and a
- X lightsource. Returns how obscuring the ball is */
- Xstruct mat *m;
- Xstruct sphere *s;
- X{
- X struct vector foops;
- X double t;
- X MTV (foops, (*m), s -> cent);
- X t = s -> rad - sqrt (foops.y * foops.y + foops.z * foops.z);
- X if (t > 0)
- X t = t / foops.x;
- X else
- X t = 0;
- X return (t);
- X}
- X
- X
- X
- X
- Xdouble shadow (p)/* finds if a point is in a shadow, or if it is on edge */
- Xstruct vector *p;
- X{
- X struct mat trans;
- X struct sphere ss;
- X struct vector d;
- X int c,
- X i;
- X double l,
- X k,
- X x,
- X y,
- X z,
- X finds ();
- X l = 0.0;
- X c = -1;
- X SV (d, ls.cent, (*p));
- X d.l = LEN (d);
- X d.xzl = XZL (d);
- X mt (&(d), &trans);
- X
- X for (i = 0; i < nob; i++) {
- X ss.rad = bl[i] -> s.rad;
- X SV (ss.cent, bl[i] -> s.cent, (*p));
- X if ((k = finds (&trans, &ss)) > l) {
- X c = i;
- X l = k;
- X }
- X }
- X if (c == -1)
- X k = 200.0;
- X else {
- X k = 1.0 - l / ((ls.rad) / (d.l));
- X if (k < 0.0)
- X k = 0.0;
- X k *= 200.0;
- X }
- X return (k);
- X}
- END_OF_find.c
- if test 1942 -ne `wc -c <find.c`; then
- echo shar: \"find.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f g_bal.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"g_bal.c\"
- else
- echo shar: Extracting \"g_bal.c\" \(652 characters\)
- sed "s/^X//" >g_bal.c <<'END_OF_g_bal.c'
- X#include <stdio.h>
- X#include "rtd.h"
- X#include "extern.h"
- Xg_bal (df)
- XFILE * df;
- X{
- X int i;
- X double x,
- X y,
- X z,
- X r,
- X ior,
- X rfr,
- X rfl,
- X dif,
- X amb;
- X for (i = 0;
- X fscanf (df, "%F %F %F %F %F %F %F %F %F",
- X &x, &y, &z, &r, &ior, &rfr, &rfl, &dif, &amb) != EOF;
- X i++) {
- X bl[i] = (struct ball *) malloc (sizeof (struct ball));
- X bl[i] -> s.cent.x = x;
- X bl[i] -> s.cent.y = y;
- X bl[i] -> s.cent.z = z;
- X bl[i] -> s.rad = r;
- X bl[i] -> ior = ior;
- X bl[i] -> rfr = rfr;
- X bl[i] -> rfl = rfl;
- X bl[i] -> dif = dif;
- X bl[i] -> amb = amb;
- X }
- X return (i);
- X}
- X
- END_OF_g_bal.c
- if test 652 -ne `wc -c <g_bal.c`; then
- echo shar: \"g_bal.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f g_bod.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"g_bod.c\"
- else
- echo shar: Extracting \"g_bod.c\" \(595 characters\)
- sed "s/^X//" >g_bod.c <<'END_OF_g_bod.c'
- X#include <stdio.h>
- X#include <math.h>
- X#include "extern.h"
- X#include "macros.h"
- X
- X
- Xg_bod (f)
- XFILE * f;
- X{
- X int k,
- X x;
- X double big = 0.0,
- X little = HUGE;
- X char buf[512];
- X
- X
- X for (ysue = 0;; ysue++) {
- X if (fgets (buf, 512, f) == NULL)
- X break;
- X xsue = strlen (buf) - 1;
- X for (x = 0; x < xsue; x++) {
- X k = buf[x];
- X suzie[x][ysue] = (double) k;
- X if (big < k)
- X big = k;
- X if (little > k)
- X little = k;
- X }
- X }
- X big = big - little;
- X for (k = 0; k < ysue; k++)
- X for (x = 0; x < xsue; x++)
- X suzie[x][k] = (suzie[x][k] - little) / big;
- X}
- END_OF_g_bod.c
- if test 595 -ne `wc -c <g_bod.c`; then
- echo shar: \"g_bod.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f macros.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"macros.h\"
- else
- echo shar: Extracting \"macros.h\" \(1116 characters\)
- sed "s/^X//" >macros.h <<'END_OF_macros.h'
- X/* some of the most important stuff in the program */
- X#define DOT(v1,v2) (v1.x*v2.x+v1.y*v2.y+v1.z*v2.z)
- X/* returns dot product of two vectors */
- X#define LN2(v) (DOT(v,v))
- X/* returns the square of the length of a vector */
- X#define LEN(v) sqrt(LN2(v))
- X/* guess */
- X#define XZL(v) sqrt(v.x*v.x+v.z*v.z)
- X/* returns the component in the xz plane of a vector */
- X#define SCMLT(sc,vct) vct.x*= sc;vct.y*= sc;vct.z*= sc;vct.l*= sc;
- X/* multiplies a vetor by a scalar */
- X#define MV(a,b,c,v) v.x= a;v.y= b;v.z= c;
- X/* makes a vector. wouldn't need this with c++ */
- X#define SV(t,u,v) t.x=u.x-v.x;t.y=u.y-v.y;t.z=u.z-v.z;
- X/*subtract vector t=u-v */
- X#define AV(t,u,v) t.x=u.x+v.x;t.y=u.y+v.y;t.z=u.z+v.z;
- X/* add vector t=u+v */
- X#define MTV(v1,m,v2) MV(DOT(m.x,v2),DOT(m.y,v2),DOT(m.z,v2),v1)
- X/* multiply transpose matrix by vector. v1=m*v2 */
- X
- X#define LEVEL 5/* levels of recursion */
- X#define RLEV 3/*don't want as many inside the ball, takes forever as it is*/
- X
- X#define XMIN 10.0
- X#define XMAX 220.0
- X#define YMIN 10.0
- X#define YMAX 170.0
- X/* window size, virtual units */
- X#define SCALE 2.0
- X/* maginification factor */
- END_OF_macros.h
- if test 1116 -ne `wc -c <macros.h`; then
- echo shar: \"macros.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f refract.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"refract.c\"
- else
- echo shar: Extracting \"refract.c\" \(2965 characters\)
- sed "s/^X//" >refract.c <<'END_OF_refract.c'
- X#include <math.h>
- X#include "rtd.h"
- X#include "macros.h"
- X#include "extern.h"
- X
- Xint rlev;
- Xint refract (r, bll)
- Xstruct ray *r;
- Xstruct ball *bll;
- X{
- X struct vector new,
- X norm;
- X struct mat trans;
- X struct ray ir;
- X double l,
- X refk (), getcapt (), capt, inside ();
- X double stupid;
- X struct sphere ss;
- X
- X SV (norm, r -> org, bll -> s.cent);
- X norm.l = bll-> s.rad;
- X
- X capt = getcapt (&norm, &(r -> dir), bll -> ior);
- X
- X
- X/* get the addition factor for the normal for refraction*/
- X stupid = refk (&(norm), &(r -> dir), bll -> ior);
- X SCMLT (stupid, norm);
- X
- X AV (ir.dir, r -> dir, norm);
- X MV (r -> org.x, r -> org.y, r -> org.z, ir.org);
- X
- X/* now get it for reflection */
- X SV (norm, r -> org, bll -> s.cent);
- X norm.l = bll -> s.rad;
- X SCMLT (1.0 / norm.l, norm);
- X stupid = 2.0 * DOT (norm, r -> dir);
- X SCMLT (stupid, norm);
- X SV (r -> dir, r -> dir, norm);
- X
- X return ((int) ((1.0 - capt) * (double) shade (r) + ((capt) * inside (&ir, bll))));
- X}
- X
- Xdouble inside (r, bll)
- Xstruct ray *r;
- Xstruct ball *bll;
- X{
- X struct vector new,
- X norm;
- X struct mat trans;
- X struct ray er;
- X double findo (), lght, l, refk (), getcapt (), capt;
- X double stupid;
- X struct sphere ss;
- X
- X
- X if (++rlev < RLEV) {
- X r -> dir.l = LEN (r -> dir);
- X r -> dir.xzl = XZL (r -> dir);
- X mt (&(r -> dir), &trans);
- X ss.rad = bll -> s.rad;
- X SV (ss.cent, bll -> s.cent, r -> org);
- X
- X l = findo (&trans, &ss);
- X MV (l * trans.x.x, l * trans.x.y, l * trans.x.z, new);
- X AV (er.org, r -> org, new);
- X AV (r -> org, r -> org, new);
- X SV (norm, er.org, bll -> s.cent);
- X
- X norm.l = bll -> s.rad;
- X capt = getcapt (&norm, &(r -> dir), 1.0 / bll -> ior);
- X
- X stupid = refk (&norm, &(r -> dir), 1.0 / bll -> ior);
- X SCMLT (stupid, norm);
- X AV (er.dir, norm, r -> dir);
- X
- X SCMLT (1.0 / norm.l, norm);
- X stupid = 2.0 * DOT (norm, r -> dir);
- X SCMLT (stupid, norm);
- X SV (r -> dir, r -> dir, norm);
- X lght = (1.0 - capt) * inside (r, bll) + (capt * (double) shade (&er));
- X }
- X else
- X lght = 0.0;
- X rlev--;
- X if (lght<0.0) lght=0.0;
- X if (lght>255.0) lght=255.0;
- X return (lght);
- X}
- X
- X
- X
- Xdouble refk (nrm, in, ior)
- Xstruct vector *nrm,
- X *in;
- Xdouble ior;
- X{
- X double dt,
- X ln,
- X li,
- X ret;
- X
- X ior = ior * ior;
- X dt = DOT ((*nrm), (*in));
- X ln = LN2 ((*nrm));
- X li = LN2 ((*in));
- X if (dt < 0)
- X ret = (-dt - sqrt (dt * dt - ln * li * (1 - ior))) / ln;
- X else
- X ret = (-dt + sqrt (dt * dt - ln * li * (1 - ior))) / ln;
- X return (ret);
- X}
- X
- Xdouble getcapt (nrm, dr, ior)
- Xstruct vector *nrm,
- X *dr;
- Xdouble ior;
- X{
- X double dt,
- X cs1,
- X cs2,
- X p,
- X s;
- X dt = DOT ((*nrm), (*dr));
- X dt = dt * dt / LN2 ((*nrm)) / LN2 ((*dr));
- X cs1 = sqrt (dt);
- X cs2 = sqrt (1.0 - (1.0 - dt) / ior);
- X p = cs1 / (cs1 + ior * cs2);
- X s = cs1 / (ior * cs1 + cs2);
- X return (2.0 * (p * p + s * s));
- X}
- END_OF_refract.c
- if test 2965 -ne `wc -c <refract.c`; then
- echo shar: \"refract.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f rtd.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"rtd.h\"
- else
- echo shar: Extracting \"rtd.h\" \(434 characters\)
- sed "s/^X//" >rtd.h <<'END_OF_rtd.h'
- Xstruct color {
- Xint r;int g;int b;};
- X
- Xstruct vector {
- Xdouble x;
- Xdouble y;
- Xdouble z;
- Xdouble l;
- Xdouble xzl;} ;
- X
- Xstruct ray {
- Xstruct vector org;
- Xstruct vector dir;} ;
- X
- Xstruct sphere {
- Xstruct vector cent;
- Xdouble rad;} ;
- X
- Xstruct ball {
- Xstruct sphere s;
- Xdouble ior;
- Xdouble rfr;
- Xdouble rfl;
- Xdouble dif;
- Xdouble amb;
- X};
- X
- Xstruct mat {
- Xstruct vector x; /* first !row! */
- Xstruct vector y; /*second !row! */
- Xstruct vector z;}; /* third !row! */
- X
- END_OF_rtd.h
- if test 434 -ne `wc -c <rtd.h`; then
- echo shar: \"rtd.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f shade.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"shade.c\"
- else
- echo shar: Extracting \"shade.c\" \(3454 characters\)
- sed "s/^X//" >shade.c <<'END_OF_shade.c'
- X/*
- X * this subroutine does all the gritty work- it calculates
- X * what shade each pixel should be. I like recursion.
- X */
- X#include <math.h>
- X#include "rtd.h"
- X#include "macros.h"
- X#include "extern.h"
- X
- Xint shade (r)
- Xstruct ray *r;
- X{
- X int i,
- X c,
- X refract ();
- X struct ray refr;
- X double lght,
- X x,
- X y,
- X z,
- X l,
- X k,
- X dot (), find (), shadow ();
- X int sx,
- X sy;
- X double stupid;
- X struct vector new,
- X norm;
- X struct mat trans;
- X struct sphere ss;
- X if (++level <= LEVEL) {
- X c = -1;
- X l = HUGE;
- X/* get vector length and xz component for mt() */
- X r -> dir.l = LEN (r -> dir);
- X r -> dir.xzl = XZL (r -> dir);
- X/* make a transform matrix that rotates something in space so
- X that the ray will be aligned with the x axis */
- X mt (&(r -> dir), &trans);
- X
- X/* for starters we find out whether we hit anything. */
- X for (i = 0; i < nob; i++) {
- X ss.rad = bl[i] -> s.rad;
- X SV (ss.cent, bl[i] -> s.cent, r -> org);
- X if ((k = find (&trans, &ss)) > 0.0 && k < l) {
- X c = i;
- X l = k;
- X }
- X }
- X if (c >= 0 && (l * trans.x.y + r -> org.y) > 0.0) {
- X /* WE HIT SOMETHING */
- X MV (l * trans.x.x, l * trans.x.y, l * trans.x.z, new);
- X new.l=l;
- X/* move the new orgin of the ray to the intersection */
- X AV (refr.org, new, r -> org);
- X AV (r -> org, new, r -> org);
- X MV (r -> dir.x, r -> dir.y, r -> dir.z, refr.dir);
- X/* get a normal vector for the intersection point */
- X SV (norm, r -> org, bl[c] -> s.cent);
- X norm.l=bl[c] ->s.rad;
- X
- X/* ambient lighting */
- X lght = 200.0 * bl[c] -> amb;
- X
- X/* shaded lighting (diffuse). subroutine shadow is in find.c */
- X if (bl[c] -> dif != 0.0) {
- X SV (new, ls.cent, r -> org);
- X new.l = LEN(new);
- X if ((k = DOT (new, norm)) > 0.0)
- X lght += bl[c] -> dif * shadow (&(r -> org)) * k / (new.l) / (norm.l);
- X }
- X
- X/*reflection... easy */
- X if (bl[c] -> rfl != 0.0) {
- X/* make the normal unit length */
- X SCMLT ((1.0 / norm.l), norm);
- X/* get the length of the ray's component in the normal direction */
- X stupid = 2.0 * DOT (norm, r -> dir);
- X SCMLT (stupid, norm);
- X/* subtract double the normal component- !reflection! */
- X SV (r -> dir, r -> dir, norm);
- X lght += bl[c] -> rfl * (double) shade (r);
- X }
- X
- X/* refraction. this is ugly, which is why I choose to deal with
- X it in it's own subroutine which comes after this one */
- X if (bl[c] -> rfr != 0.0) {
- X lght += bl[c] -> rfr * (double) refract (&refr, bl[c]);
- X }
- X
- X
- X
- X }
- X else { /* hit no objects... */
- X if ((r -> dir.y) < 0.0) {/* crosses floor */
- X z = -(r -> org.y) / (r -> dir.y);
- X (r -> org.x) += z * (r -> dir.x);
- X (r -> org.z) += z * (r -> dir.z);
- X (r -> org.y) = 0.0;
- X
- X SV (new, ls.cent, r -> org);
- X new.l = LEN(new);
- X sx = (int) (r -> org.x / 1.5) % xsue;
- X if (sx < 0)
- X sx += xsue;
- X sy = -(int) (r -> org.z / 1.5) % ysue;
- X if (sy < 0)
- X sy += ysue;
- X lght = (sam * suzie[sx][sy] + 1.0 - sam) * (0.8 *
- X shadow (&(r -> org)) * (new.y) / (new.l) + 40.0);
- X
- X
- X }
- X else { /* check to see if it hit lightsource */
- X SV (ss.cent, ls.cent, r -> org);
- X ss.rad = ls.rad;
- X if (find (&trans, &(ss.cent)) > 0.0)
- X lght = 255;
- X else
- X lght = 0;
- X }
- X }
- X }
- X/* to many levels return 0 cause it shouldn't matter */
- X else
- X lght = 0;
- X level--;
- X if (lght < 0.0)
- X lght = 0.0;
- X if (lght > 255.0)
- X lght = 255.0;
- X return ((int) lght);
- X}
- END_OF_shade.c
- if test 3454 -ne `wc -c <shade.c`; then
- echo shar: \"shade.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f support.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"support.c\"
- else
- echo shar: Extracting \"support.c\" \(834 characters\)
- sed "s/^X//" >support.c <<'END_OF_support.c'
- X/*
- X * supportive subroutines...
- X */
- X
- X#include <math.h>
- X#include <stdio.h>
- X#include "rtd.h"
- X#include "extern.h"
- X
- X
- Xmt (vec, trans)
- Xstruct vector *vec;
- Xstruct mat *trans;
- X{
- X if (vec -> xzl == 0.0) {
- X trans -> x.x = 0.0;
- X trans -> x.y = 1.0;
- X trans -> x.z = 0.0;
- X trans -> y.x = -1.0;
- X trans -> y.y = 0.0;
- X trans -> y.z = 0.0;
- X trans -> z.x = 0.0;
- X trans -> z.y = 0.0;
- X trans -> z.z = 1.0;
- X }
- X else {
- X trans -> x.x = (vec -> x) / (vec -> l);
- X trans -> x.y = (vec -> y) / (vec -> l);
- X trans -> x.z = (vec -> z) / (vec -> l);
- X trans -> y.x = -(vec -> x) * (vec -> y) / ((vec -> l) * (vec -> xzl));
- X trans -> y.y = (vec -> xzl) / (vec -> l);
- X trans -> y.z = -(vec -> z) * (vec -> y) / ((vec -> l) * (vec -> xzl));
- X trans -> z.x = -(vec -> z) / (vec -> xzl);
- X trans -> z.y = 0;
- X trans -> z.z = (vec -> x) / (vec -> xzl);
- X }
- X}
- END_OF_support.c
- if test 834 -ne `wc -c <support.c`; then
- echo shar: \"support.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f tracer.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"tracer.c\"
- else
- echo shar: Extracting \"tracer.c\" \(2624 characters\)
- sed "s/^X//" >tracer.c <<'END_OF_tracer.c'
- X
- X
- X/* tracer version 2.1 */
- X#include <stdio.h>
- X#include <math.h>
- X#include "rtd.h"
- X#include "macros.h"
- X
- X
- XFILE * fp;
- Xdouble suzie[300][300],
- X sam = 1.0;
- Xint xsue,
- X ysue;
- Xstruct ball *bl[150];
- Xint level,
- X nob;
- Xstruct sphere ls;
- X
- Xmain (argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X FILE * df, *texfile;
- X static double xco,
- X yco;
- X struct ray rr;
- X struct vector vp;
- X double x,
- X y,
- X z;
- X int i,
- X in = 0,
- X out = 0,
- X tex = 0;
- X int c;
- X
- X/* command interp */
- X
- X for (i = 1; i < argc; i++) {
- X if (argv[i][0] != '-')
- X booboo ("Options strt with a '-' bozo");
- X c = argv[i][1];
- X
- X switch (c) {
- X case ('i'):
- X if (in)
- X booboo ("Sorry, but you may only have one input file");
- X in = 1;
- X if ((i + 1) >= argc || argv[i + 1][0] == '-')/* no arg */
- X df = stdin;
- X else
- X if ((df = fopen (argv[++i], "r")) == NULL)
- X booboo ("input file not found");
- X break;
- X case ('o'):
- X if (out)
- X booboo ("Sorry, but you may have only one output file");
- X out = 1;
- X if ((i + 1) >= argc || argv[i + 1][0] == '-')/* no arg */
- X fp = stdout;
- X else
- X fp = fopen (argv[++i], "w");
- X break;
- X case ('s'):
- X if (tex)
- X booboo ("Sorry, but you may have only one image file");
- X if ((i + 1) >= argc || argv[i + 1][0] == '-')/* no arg */
- X booboo ("-s requires an argument");
- X tex = 1;
- X if ((texfile = fopen (argv[++i], "r")) == NULL)
- X booboo ("image file not found");
- X break;
- X booboo ("this line shouldn't do anything");
- X case ('S'):
- X if (argv[i][2] < '0' || argv[i][2] > '9'){
- Xprintf("%c\n",argv[i][2]);
- X booboo ("-S needs a numerical argument");}
- X sam = atof (&(argv[i][2]));
- X break;
- X default:
- X booboo ("Unrecognized option. Better try again");
- X }
- X }
- X
- X
- X if (!in)
- X if ((df = fopen ("bdata.i", "r")) == NULL)
- X booboo ("bdata.i not found");
- X if (!out)
- X fp = fopen ("data.dis", "w");
- X if (!tex)
- X if ((texfile = fopen ("pat.def", "r")) == NULL)
- X booboo ("pat.def not found");
- X
- X
- X
- X nob = g_bal (df);
- X g_bod (texfile);
- X
- X
- X
- X MV (95.0, 140.0, -200.0, vp);
- X MV (0.0, 900.0, 0.0, ls.cent);
- X ls.rad = 40;
- X fprintf (fp, "%d %d\n", (int) ((XMAX - XMIN) * SCALE +0.9999999), (int) ((YMAX - YMIN) * SCALE +0.9999999));
- X
- X for (yco = YMAX * SCALE; yco > YMIN * SCALE; yco--)
- X for (xco = XMIN * SCALE; xco < XMAX * SCALE; xco++) {
- X MV (xco / SCALE, yco / SCALE, 0.0, rr.org);
- X SV (rr.dir, rr.org, vp);
- X fprintf (fp, "%c", shade (&rr));
- X }
- X}
- X
- Xbooboo (str)
- Xchar *str; {
- X printf ("%s\n", str);
- X exit (-1);
- X}
- END_OF_tracer.c
- if test 2624 -ne `wc -c <tracer.c`; then
- echo shar: \"tracer.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of shell archive.
- exit 0
-